import 'dart:convert';
import 'dart:io';

import 'package:dio/adapter.dart';
import 'package:flutter_application_cyber/model/cn_net_response.dart';
import '../model/cn_responseModel.dart';
import '../tools/cn_constant_pool.dart';
import 'cn_net_interceptor.dart';
import 'package:dio/dio.dart';
import 'package:flutter_application_cyber/net/cn_net_api.dart';
import 'package:flutter_application_cyber/tools/cn_event_bus.dart';

class CnNetService {
  // 静态变量指向自身
  static final CnNetService _instance = CnNetService._();

  // 方案1：静态方法获得实例变量
  // static CnNetService getInstance() => _instance;
  // // 方案2：工厂构造方法获得实例变量
  factory CnNetService() => _instance;

  // // 方案3：静态属性获得实例变量
  // static Singleton get instance => _instance;

  ///构造函数私有化，防止被误创建
  // CnNetService._instance();

  //dio 实例
  Dio? dio;

  //私有构造器
  CnNetService._() {
    if (dio == null) {
      //
      BaseOptions baseOptions = BaseOptions(
          baseUrl: CnApiNet.BASE_URL,
          connectTimeout: CnApiNet.CONNECT_TIMEOUT,
          receiveTimeout: CnApiNet.RECEIVE_TIMEOUT,
          headers: {});
      //实例
      dio = Dio(baseOptions);
      //添加拦截
      dio!.interceptors.add(CnHttpInterceptor());
      (dio?.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
          (client) {
        // config the http client
        client.badCertificateCallback =
            (X509Certificate cert, String host, int port) {
          return true;
        };
        // you can also create a HttpClient to dio
        // return HttpClient();
      };
    }
  }

  void init(
    String baseUrl,
    int connectTimeout,
    int receiveTimeout,
    Map<String, dynamic> headers,
    List<Interceptor> interceptors,
  ) {
    dio!.options.baseUrl = baseUrl;
    dio!.options.connectTimeout = connectTimeout;
    dio!.options.receiveTimeout = receiveTimeout;
    dio!.options.headers = headers;
    if (interceptors != null && interceptors.isNotEmpty) {
      dio!.interceptors.addAll(interceptors);
    }
  }

  //设置请求头
  void setHeaders(Map<String, dynamic> headers) {
    dio!.options.headers.addAll(headers);
  }

  CancelToken _cancelToken = CancelToken();

  void cancelRequests({CancelToken? token}) {
    token ?? _cancelToken.cancel('cancelled');
  }

  //设置鉴权请求头
  Options setAuthorizationHeader(Options requestOptions) {
    String? _token;
    if (_token != null && requestOptions.headers != null) {
      requestOptions.headers!['token'] = _token;
    }
    return requestOptions;
  }

//restful get
//请求超时或错误放回null，注意判空
  Future get(
    String path, {
    Map<String, dynamic>? params,
    Options? options,
    CancelToken? cancelToken,
  }) async {
    Options requestOptions = setAuthorizationHeader(options ?? Options());
    requestOptions.contentType = 'application/json;charset=UTF-8';

    try {
      Response response = await dio!.get(
        path,
        options: requestOptions,
        queryParameters: params,
        cancelToken: cancelToken ?? _cancelToken,
      );

      var responseData = HDHResponse(
          data: response.data,
          statuscode: response.statusCode,
          statusmessage: response.statusMessage);
      tokenExpireCode(responseData);
      HDHResponseData data = HDHResponseData.fromJson(responseData.data);
      return data;
    } catch (e) {
      HDHResponseData errData = HDHResponseData.fromJson(
          {'code': 1, 'success': false, 'msg': 'error', 'data': null});
      return errData;
    }
  }

//restfult post
// 请求超时或错误放回null，注意判空
  Future post(
    String path, {
    dynamic params,
    dynamic data,
    Options? options,
    CancelToken? cancelToken,
  }) async {
    try {
      Response response = await dio!.post(
        path,
        data: params,
        options: options,
        cancelToken: cancelToken ?? _cancelToken,
      );

      var responseData = HDHResponse(
          data: response.data,
          statuscode: response.statusCode,
          statusmessage: response.statusMessage);
      tokenExpireCode(responseData);
      HDHResponseData data = HDHResponseData.fromJson(responseData.data);
      return data;
    } catch (e) {
      HDHResponseData errData = HDHResponseData.fromJson(
          {'code': 1, 'success': false, 'msg': 'error', 'data': null});
      return errData;
    }
  }

  Future loginPost(
    String path, {
    required Map<String, dynamic> params,
    Options? options,
    CancelToken? cancelToken,
  }) async {
    try {
      Response response = await dio!.post(
        path,
        queryParameters: params,
        options: options,
        cancelToken: cancelToken ?? _cancelToken,
      );

      var responseData = HDHResponse(
          data: response.data,
          statuscode: response.statusCode,
          statusmessage: response.statusMessage);
      tokenExpireCode(responseData);
      HDHResponseData data = HDHResponseData.fromJson(responseData.data);
      return data;
    } catch (e) {
      HDHResponseData errData = HDHResponseData.fromJson(
          {'code': 1, 'success': false, 'msg': 'error', 'data': null});
      return errData;
    }
  }

//restful post form表单
  Future postForm(
    String path, {
    Map<String, dynamic>? params,
    Options? options,
    CancelToken? cancelToken,
  }) async {
    Options requestOptions = setAuthorizationHeader(options ?? Options());

    dynamic tmpData;
    if (params != null) {
      tmpData = FormData.fromMap(params);
    }

    Response response = await dio!.post(
      path,
      data: tmpData,
      queryParameters: params,
      options: requestOptions,
      cancelToken: cancelToken ?? _cancelToken,
    );
    return response;
    // var cRsp = HDHResponse(data: response.data,hashcode: response.hashCode,statuscode: response.statusCode,statusmessage: response.statusMessage);
    // return cRsp;
  }

  //上传图片
  Future postUpLoadImage(
    String path, {
    Options? options,
    dynamic data,
    CancelToken? cancelToken,
  }) async {
    Options requestOptions = setAuthorizationHeader(options ?? Options());

    Response response = await dio!.post(
      path,
      data: data,
      options: requestOptions,
      cancelToken: cancelToken ?? _cancelToken,
    );

    var responseData = HDHResponse(
        data: response.data,
        statuscode: response.statusCode,
        statusmessage: response.statusMessage);

    HDHResponseData hDHResponseData =
        HDHResponseData.fromJson(jsonDecode(responseData.data));
    return hDHResponseData;
  }

  //发送Token过期消息       {"data":"{\"code\":10010303,\"fail\":true,\"key\":\"security_tokenTimeOut\",\"msg\":\"token is expire\",\"success\":false}","statusCode":200,"statusMessage":""}
  tokenExpireCode(HDHResponse response) {
    try {
      Map<String, dynamic> jsonData = json.decode(response.data ?? "");
      CnResponseModel responseModel = CnResponseModel.fromJson(jsonData);
      if (responseModel.code == CnConstantPool.TOKEN_EXPIRE_CODE) {
        CnEventBus.instance?.commit(EventKeys.onTokenExpireCode, Null);
      }
    } catch (e) {
      HDHResponseData errData = HDHResponseData.fromJson(
        {'code':1,
        'success':false,
        'msg':'error',
        'data':null});
      return errData;
    }
  }
}
